import { defineStore } from "pinia"
import { computed, reactive, ref } from 'vue'
import { Subject } from "@/seed-application/types"
import { useWatermark } from '@/hooks/web/useWatermark'
import { getApp } from "@/seed-application"
import { endSwitchApi, subjectApi } from "@/api"
import feedback from "@/utils/feedback"
import { useTagsViewStore } from ".."

const { setWatermark, clear } = useWatermark()

interface LoginInfo {
  subject?: Subject,
  switchTo?: Subject
}

export default defineStore('userStore', () => {
  const app = getApp()
  const loginKey = ref((app.owner ? `${app.owner}.` : '') + `${app.name}.loginInfo`)
  const loginInfo = reactive<LoginInfo>(getLoginInfo())
  
  async function login() {
    loginInfo.switchTo = undefined
    loginInfo.subject = await subjectApi()
    localStorage?.setItem(loginKey.value, JSON.stringify(loginInfo))

    setWatermark(loginInfo.subject.name)
  }

  function switchTo(subject: Subject) {
    if(isLogin) {
      loginInfo.switchTo = subject
      localStorage?.setItem(loginKey.value, JSON.stringify(loginInfo))
      const tagsViewStore: any = useTagsViewStore()
      tagsViewStore.delAllViews()
    } else {
      feedback.alertError('请先登录')
    }
  }

  async function endSwitch() {
    await endSwitchApi()
    loginInfo.switchTo = undefined
    localStorage?.setItem(loginKey.value, JSON.stringify(loginInfo))

    const tagsViewStore: any = useTagsViewStore()
    tagsViewStore.delAllViews()
  }

  function logout() {
    loginInfo.subject = undefined
    loginInfo.switchTo = undefined

    localStorage?.removeItem(loginKey.value)
    clear()
  }

  function getLoginInfo() {
    const item = localStorage?.getItem(loginKey.value)

    const ret = item ? JSON.parse(item) : {}
    setWatermark(ret.subject?.name)
    return ret
  }

  const account = computed(() => loginInfo.switchTo?.account || loginInfo.subject?.account)
  const name = computed(() => loginInfo.switchTo?.name || loginInfo.subject?.name)
  const avatar = computed(() => loginInfo.switchTo?.avatar || loginInfo.subject?.avatar)
  const getSubject = computed(() => loginInfo.subject)
  const getSwitchTo = computed(() => loginInfo.switchTo)
  const positions = computed(() => loginInfo.subject?.positions)
  const permissions = computed(() => loginInfo.switchTo?.permissions || loginInfo.subject?.permissions)
  const fullPermissions = computed(() => loginInfo.switchTo?.fullPermissions || loginInfo.subject?.fullPermissions)
  const isLogin = computed(() => loginInfo.subject)
  const isSwitch = computed(() => loginInfo.switchTo)

  const modules = computed(() => {
    const items = []
    for(const item of (permissions.value || [])) items.push(item.substring(0, item.lastIndexOf('.')))

    const ret: Record<string, string[]> = {}
    for(const item of items) {
      const microAndModule = item.split('.')
      if(microAndModule.length == 1) {
        const value = ret[''] || []
        if(!value.includes(item)) value.push(item)
        ret[''] = value
      } else {
        const [microName, seedName] = microAndModule
        const value = ret[microName] || []
        if(!value.includes(seedName)) value.push(seedName)
        ret[microName] = value
      }
    }

    return ret
  })

  function assignable(permission: string) {
    return fullPermissions.value.includes('*') || fullPermissions.value.includes(permission);
  }

  function has(permission: string) {
    return assignable(permission) && (permissions.value.includes('*') || permissions.value.includes(permission));
  }

  return {
    isLogin,
    isSwitch,
    login,
    logout,
    switchTo,
    endSwitch,
    loginKey,
    loginInfo,
    account,
    name,
    avatar,
    getSubject,
    getSwitchTo,
    positions,
    permissions,
    fullPermissions,
    modules,
    assignable,
    has
  }
})
